package com.bear.richtext.utils

import com.bear.richtext.type.RichItem
import com.bear.richtext.type.RichItemType
import org.json.JSONArray
import org.json.JSONObject

/**
 * 富文本控件所支持的一些节点
 */
class RichTextNode {

    val body: HashMap<String, Any> = HashMap()

    fun toJson(): JSONObject {
        val jsonObject = JSONObject()
        body.forEach {
            if (it.value is RichTextNode) {
                jsonObject.put(it.key, (it.value as RichTextNode).toJson())
            } else {
                jsonObject.put(it.key, it.value)
            }
        }
        return jsonObject
    }

    //invoke约定和扩展方法
    inline operator fun String.invoke(block: RichTextNode.() -> Unit): RichTextNode {
        val node = RichTextNode()
        node.block()
        this@RichTextNode.body[this] = node
        return node
    }

    //中缀表达式
    infix inline fun <T> String.to(value: T) {
        this@RichTextNode.body[this] = value!!
    }
}

fun JsonNode(block: RichTextNode.() -> Unit): JSONObject {
    val node = RichTextNode()
    node.block()
    return node.toJson()
}

fun <T> array(vararg values: T): JSONArray {
    val jsonArray = JSONArray()
    for (value in values) {
        jsonArray.put(value)
    }
    return jsonArray
}

//图片标签
fun Image(block: RichTextNode.() -> Unit): JSONObject {
    return selfLabel(RichItemType.Image.name, block)
}

//正文文本
fun Text(block: RichTextNode.() -> Unit): JSONObject {
    return selfLabel(RichItemType.Text.name, block)
}

//gif图片
fun Gif(block: RichTextNode.() -> Unit): JSONObject {
    return selfLabel(RichItemType.Gif.name, block)
}

//文本标签
fun Tag(block: RichTextNode.() -> Unit): JSONObject {
    return selfLabel(RichItemType.Tag.name, block)
}

//可点击文本
fun Clickable(block: RichTextNode.() -> Unit): JSONObject {
    return selfLabel(RichItemType.Clickable.name, block)
}

//换行符标签
fun NewLine(block: RichTextNode.() -> Unit): JSONObject {
    return selfLabel(RichItemType.NewLine.name, block)
}

private fun selfLabel(label: String, block: RichTextNode.() -> Unit): JSONObject {
    val node = RichTextNode()
    node.block()
    val attrs = node.toJson()
    val newNode = RichTextNode()
    newNode.body[RichItem.TYPE] = label
    newNode.body[RichItem.ATTRS] = attrs
    return newNode.toJson()
}
